﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SampleImageGenerator.Core;
using SampleImageGenerator.Core.Events;
using System.IO;

namespace SampleImageGenerator.Controls
{
	internal partial class BatchModeGui : EngineListenerControl
	{
		public BatchModeGui()
		{
			InitializeComponent();

			EnableSaveOptions(cbSaveImages.Checked);
		}

		protected override void UpdateState(IEngine engine)
		{
			BusyGui(engine.Busy);
		}

		private void BusyGui(Boolean busy)
		{
			tableImageOptions.Enabled = !busy;
			panelSaveOptions.Enabled = !busy;
			btnGo.Enabled = !busy;
			btnCancel.Enabled = busy;
		}

		protected override void AttachEventHandlers(IEngine engine)
		{
			engine.BusyChanged += EngineBusyChangedHandler;
			engine.ImageGenerated += ImageGeneratedInvoker;
		}

		protected override void DetachEventHandlers(IEngine engine)
		{
			engine.BusyChanged -= EngineBusyChangedHandler;
			engine.ImageGenerated -= ImageGeneratedInvoker;
		}
	
		private void EngineBusyChangedHandler(object sender, EventArgs e)
		{
			if (this.InvokeRequired)
			{
				Object[] args = new Object[] { sender, e };
				EventHandler handler = EngineBusyChangedHandler;
				this.Invoke(handler, args);
			}
			else
			{
				BusyGui(Engine.Busy);
			}
		}


		private void ImageGeneratedInvoker(object sender, ImageGeneratedEventArgs e)
		{
			if (this.InvokeRequired)
			{
				Object[] args = new Object[] { sender, e };
				EventHandler<ImageGeneratedEventArgs> handler = ImageGeneratedHandler;
				this.Invoke(handler, args);
			}
			else
			{
				ImageGeneratedHandler(sender, e);
			}
		}

		private void ImageGeneratedHandler(object sender, ImageGeneratedEventArgs e)
		{
			if (cbSaveImages.Checked)
			{
				Image image = e.GetImage();
				String imageFolder = tbOutputFolder.Text;
				String imageFilename = String.Format("{0}-{1}.jpg", tbImagePrefix.Text, e.Id);
				String imagePath = Path.Combine(imageFolder, imageFilename);
				image.Save(imagePath); 
			}
		}

		private void cbSaveImages_CheckedChanged(object sender, EventArgs e)
		{
			EnableSaveOptions(cbSaveImages.Checked);
		}

		private void EnableSaveOptions(Boolean enable)
		{
			panelSaveOptions.Enabled = enable;
		}

		private void btnOutputFolderBrowse_Click(object sender, EventArgs e)
		{
			using (FolderBrowserDialog browser = new FolderBrowserDialog())
			{
				browser.Description = "Select location to generate sample images";
				browser.ShowNewFolderButton = true;

				DialogResult result = browser.ShowDialog();
				if (result == DialogResult.OK)
				{
					tbOutputFolder.Text = browser.SelectedPath;
				}
			}
		}

		private void btnGo_Click(object sender, EventArgs e)
		{
			try
			{
				Int32 imageWidth = Convert.ToInt32(nudImageWidth.Value);
				Int32 imageHeight = Convert.ToInt32(nudImageHeight.Value);
				Int32 imageCount = Convert.ToInt32(nudImageCount.Value);
				Int32 seed = Convert.ToInt32(nudSeed.Value);

				BatchModeOptions options = new BatchModeOptions(
					imageWidth,
					imageHeight,
					imageCount,
					seed);

				Engine.GenerateImageBatchAsync(options);
			}
			catch (Exception ex)
			{
				GuiUtilities.HandleException(ex); 
			}
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			try
			{
				Engine.RequestCancellationAsync();
			}
			catch (Exception ex)
			{
				GuiUtilities.HandleException(ex);
			}
		}
	}
}
